//
//  SendMessageMethodInvokedViewController.swift
//  iOS-RxSwift-Tutorials_Example
//
//  Created by mengru.tian on 2020/9/24.
//  Copyright © 2020 CocoaPods. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

class SendMessageMethodInvokedViewController: UIViewController {

    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        title = "54.sendMessage和methodInvoked的区别"
        view.backgroundColor = .white
        
        test()
        test2()
         
        //调用自定义方法
        test3("hangge.com")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("2")
    }
    
    func test() {
        //使用sentMessage方法获取Observable
        self.rx.sentMessage(#selector(SendMessageMethodInvokedViewController.viewWillAppear(_:)))
            .subscribe(onNext: { value in
                print("1")
            })
            .disposed(by: disposeBag)
         
        //使用methodInvoked方法获取Observable
        self.rx.methodInvoked(#selector(SendMessageMethodInvokedViewController.viewWillAppear(_:)))
            .subscribe(onNext: { value in
                print("3")
            })
            .disposed(by: disposeBag)
    }
    
    func test2() {
        //使用sentMessage获取方法执行前的序列
        self.rx.sentMessage(#selector(SendMessageMethodInvokedViewController.test3))
            .subscribe(onNext: { value in
                print("1：\(value[0])")
            })
            .disposed(by: disposeBag)
         
        //使用methodInvoked获取方法执行后的序列
        self.rx.methodInvoked(#selector(SendMessageMethodInvokedViewController.test3))
            .map({ (a) in
                return try self.castOrThrow(String.self, a[0])
            })
            .subscribe(onNext: { value in
                print("3：\(value)")
            })
            .disposed(by: disposeBag)
    }
    
    //自定义方法
    @objc dynamic func test3(_ value:String) {
        print("2：\(value)")
    }

    //转类型的函数（转换失败后，会发出Error）
    fileprivate func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
        guard let returnValue = object as? T else {
            throw RxCocoaError.castingError(object: object, targetType: resultType)
        }
        return returnValue
    }
}
